#!/usr/bin/env bash

#########################################
# Describe: 封装常用函数
# Version: v1.0
# Author: cz
#########################################

# 定义脚本工作的根目录：
shell_work_path='/home/acctuser/'

split() {
  str=$1
  split_symbol=$2
  num=$3
  echo `echo $str | awk -v a=${num} -F $split_symbol '{print $a}'`
}

# TODO 后续将操作命令抽取出来, make it a public script, user only need to enter command
main() {
  # 定义一个分隔符
  split_symbol="|"
  filenames=`sed -n '/^[^#]/p' filenamelist`

  for filename in $filenames
    do
      filename1=`split "$filename" "$split_symbol" 1`
      tablename1=`split "$filename" "$split_symbol" 1`
      # 执行命令
      $(load data infile 'sftp://gbase:gbase@10.9.237.90/home/gbase/$filename1' into table)
      $($tablename1 data_format 4 fields length '2,25,14,14,27,1,1,16,1,14,1,29,15,0,0' set FILE_NAME_999 = '$filename1')
    done

  return 0
}

# 获取指定文件夹下的所有文件名称
get_folder_filename() {

  for filename in $(ls $1)
    do
      echo $filename
    done
}

# 获取指定文件夹下的所有文件名称集合
get_folder_filename_list() {

  for filename in $(ls $1)
    do
      echo $filename
    done
}


# 获取指定文件夹下的文件总数
get_folder_filecount() {
  folder=$1
  command=`ls -l $folder |grep "^-"|wc -l`
  echo $command
}

# 获取指定文件夹下的目录总数
get_folder_count() {
  folder=$1
  command=`ls -l $folder |grep "^d"|wc -l`
  echo $command
}

# 将指定内容追加到文件中
write_to_file() {
  echo $1 >> $2
}

# 截取指定分隔符分割后的最后一个字符 q|w|e|r  result:r
get_last_str() {
  str=$1
  split_symbol=$2
  echo ${str##*$split_symbol}
}

# 截取指定分隔符分割后不包含第一个字符的其他字符 q|w|e|r  result:|w|e|r
get_exclude_first_str() {
  str=$1
  split_symbol=$2
  echo ${str#*$split_symbol}
}

# 截取指定分隔符分割后的第一个字符 q|w|e|r  result:q   %表示从右边截取  ##表示从左边截取
get_first_str() {
  str=$1
  split_symbol=$2
  echo ${str%%$split_symbol*}
}

# 截取指定分隔符分割后不包含最后一个字符的其他字符 q|w|e|r  result:q|w|e|
get_exclude_last_str() {
  str=$1
  split_symbol=$2
  echo ${str%$split_symbol*}
}

# 将jar包中的指定class替换掉
hot_path() {
  jar_path=$1
  class_path=$2
  # 获取类名称
  class_name=`get_last_str $2 '/'`
  # 从jar包中获取真实的类路径
  real_class_path=`jar tf $jar_path | grep $class_name`
  class_folder=`get_exclude_last_str $real_class_path '/'`
  # 创建文件夹
  mkdir -p ./$class_folder
  # 把class文件复制过来
  cp $class_path ./$class_folder
  # 执行替换
  result=`jar -uvf $jar_path ./$real_class_path`

  echo $result
  # 替换完成后，删除临时文件夹 rm -rf ./com
  first_folder=`get_first_str $class_folder '/'`
  rm -rf ./$first_folder
}

# 替换指定路径的文件
replace_specify_file() {
  file_name=$1
  file_path=$2
  cp $1 $2
}

# 查找并替换主机上所有的路径
find_and_replace() {
  work_path=$1
  file_name=$2
  # 获取当前路径
  current_path=`pwd`
  current_full_path="$current_path/$file_name"
  count=0
  all_file_path=`find_by_name $work_path $file_name`
  for filepath in $all_file_path
    do
      if [[ $current_full_path == $filepath ]]
        then
          continue
      fi
      replace_specify_file $file_name $filepath
      count=`expr $count + 1`

   done

  echo 'find and replace' $count
}

# 指定目录下查找指定文件
find_by_name() {
  work_path=$1
  file_name=$2
  # result=`find $1 -name $2` 接收后再输出不换行
  find $1 -name $2
}

# 自动编译java 注意这里的java文件需要指定全路径
compile_java() {
  java_file_name=$1
  depends=$2
  CLASSPATH="`find $depends -name "*.jar" | xargs | sed "s\ \:\g"`"
  CLASSPATH=" $depends/classes:./servlet-api.jar:$CLASSPATH"
  javac -encoding UTF-8 -cp $CLASSPATH $java_file_name
}

# 热替换
hotswap_java() {
  java_file_name=$1
  process_id=$2

  if [[ $process_id == 'ims' || $process_id == 'IMS' ]]
    then
      process_id=`jps -v | grep ims | awk -F '  *' '{print $1}'`
  elif [[ $process_id == 'ejb' || $process_id == 'EJB' ]]
    then
      process_id=`jps -v | grep ejb | awk -F '  *' '{print $1}'`
  elif [[ $process_id == 'amsweb' || $process_id == 'AMSWEB' ]]
    then
      process_id=`jps -v | grep amsweb | awk -F '  *' '{print $1}'`
    fi

  java -Xbootclasspath/a:./tools.jar -jar ./hotswap-jdk.jar $process_id $java_file_name
}

find_info() {

  file_name=$1
  current_path=`pwd`
  find $current_path -name $file_name -exec ls -lh {} \;
}

# 多线程操作
parallel_handle() {
  # 最大进程数
  PROCESS_NUM=$1
  # 使用mkfifo命令可以使用指定的名称创建先进先出文件(FIFO)
  # 创建一个fifo文件
  FIFO_FILE=./$.fifo
  mkfifo $FIFO_FILE

  # 关联fifo文件和fd6
  exec 6<>$FIFO_FILE      # 将fd6指向fifo类型
  rm $FIFO_FILE

  # 向fd6中输入$PROCESS_NUM个回车
  echo ${PROCESS_NUM}
  for((idx=0;idx<${PROCESS_NUM};idx++))
  do
    echo
  done >&6

}

# 指定文件夹下的文件并行搜索
# 支持 grep key_word file_name
grep_specified_folder () {

  # 获取指定文件夹
  folder=$1
  # 需要grep的关键字
  key_word=$2
  # 定义线程数,如果未定义则默认为5，如何判断是未定义呢，通过参数个数来判断
  PROCESS_NUM=5
  if [ $# -eq 3 ]
    then
      PROCESS_NUM=$3
  fi
  # 临时文件名
  temporary_file_name='~jef_temp_file'
  # 开启多线程
  parallel_handle $PROCESS_NUM

  for filename in $(ls $folder)
    do
      read -u6
       # 每个线程处理一个gerp
      {
        result=`grep $key_word $folder/$filename`
        # 将结果追加到文件中
        echo "=============="$filename"===========" >> $temporary_file_name
        echo "$result" >> $temporary_file_name
        # 当进程结束以后，再向fd6中加上一个回车符，即补上了read -u6减去的那个
        echo  >&6
      }&
    done

  # 等待所有的任务执行完毕
  wait

  # 关闭fd6
  exec 6>&-

  cat $temporary_file_name
  rm $temporary_file_name
}

# ls展示目录大小
ls_size () {
  unit=m

  if [[ $1 == -* ]] ; then
    param=$1
    unit=${param##*-}
  fi
  ls -l --block-size=$unit

}

# 使用nmon工具生成系统性能监控文件
# nmon命令格式：nmon [ -s < seconds >] [ -c < count >] [ -b ] [ -B ] [ -g < filename >] [ -k disklist ] [ -C < process1:process2:..:processN >] [ -i ]
# c : 显示cpu利用率数据
# m：显示内存数据
# n：显示网络信息
# d：显示磁盘信息
# t：系统进程信息
# h：查看帮助信息
# q：退出Nmon界面
# 使用命令监控所有指标：forexample: ./nmon -ft -s 10 -c 60 -m /path
# -f   监控结果以文件形式输出，默认机器名+日期.nmon格式 （YYYYMMDD_HHMM.nmon）
# -F   指定输出的文件名，比如test.nmon
# -s   指的是采样的频率，单位为毫秒
# -c   指的是采样的次数，即以上面的采样频率采集多少次
# -m   指定生成的文件目录
monitor_system_start () {

  # 频率默认为1000ms采集一次
  frequency=1000
  # 采样次数默认为60次
  count=60
  # 默认保存路径
  save_path=$shell_work_path'tools/nmonData/'

  if [ "$1" != "" ]; then
    frequency=$1
  fi

  if [ "$2" != "" ]; then
    count=$2
  fi

  if [ "$3" != "" ]; then
    save_path=$3
  fi

  commond=$shell_work_path'tools/nmon/jef_nmon -ft -s '$frequency' -c '$count' -m '$save_path
  $commond
  echo "start success"
}

# 强制停止指令
monitor_system_stop () {
  commond="ps -ef | grep jef_nmon | grep -nv 'grep' | awk -F ' *' '{print $"2"}'"
  pid=`eval $commond`
  echo $pid
  kill -9 $pid
  echo "stop success PID="$pid
}

# 兜取日志中的特定sql语句，比如指定update
get_specify_sql () {

  file_name=$1
  operate=$2
  commond="grep 'ORM - ' $file_name | grep '$operate' | grep -v 'AiLogSupport' | awk -F'ORM -' '{print $"2"}'"
  commond_pro=`eval $commond`
  echo "$commond_pro" # 加了双引号之后可以换行，不加默认是一行
}

# 获取所有的DMLsql语句+条件+耗时情况
get_all_dml_sql () {
  file_name=$1
  get_specify_sql $file_name 'select\|update\|insert\|delete'
}

# 获取指定dml操作的简单sql
get_single_sql() {
  file_name=$1
  operate=$2
  all_dml_sql=`get_specify_sql $file_name $operate`
  all_single_sqls=`echo "$all_dml_sql" | grep -v "\\#" | awk -F"[|]" '{print $1}'`
  # 去除空格并踢重
  echo "$all_single_sqls" | sed -e 's/^[ ]*//g' | sed -e 's/[ ]*$//g' | awk '!a[$0]++{print}'
}

# 获取所有简单sql
get_all_single_sql() {
  file_name=$1
  get_single_sql $file_name 'select\|update\|insert\|delete'
}

get_all_single_sql_with_cost() {
  file_name=$1
  all_dml_sql=`get_specify_sql $file_name 'select\|update\|insert\|delete'`

}

query_sharding() {
  table_name=$1
  date=$2
  endDate=$4
  file_path=$3
  jarfile=$file_path'/fast-sharding-query-1.0-SNAPSHOT-start.jar'
  result=`java -jar -Djef.properties=file://$file_path/jef.properties -Dsharding.tablename=$table_name -Dsharding.acctid=0 -Dsharding.start.date=$date -Dsharding.end.date=$endDate -Dsharding.single=true -Dloglevel=error -Dorg.slf4j.simpleLogger.defaultLogLevel=error $jarfile`
  echo $result
}

command_array=("querysharding" "getsql" "monsysstop" "monsysstart" "ls" "write" "split" "help" "hotpatch" "laststr" "firststr" "nlaststr" "nfirststr" "find" "replace" "replaceall" "javac" "javacims" "javacejb" "javacamsweb" "javacother" "hotswap" "grepfolder" "findinfo" "ls")
if [ $# -lt 1 ]; then
    echo "请明确指令："
    length=${#command_array[@]}
    for ((i=0;i<$length; i++));
        do
        echo ${command_array[$i]}
        done
    exit
else

  if [[ $1 == "lsfile" || $1 == "-lsfile" || $1 == "LSFILE" ]]
   then
     get_folder_filename $2
  elif [[ $1 == "write" || $1 == "-write" || $1 == "WRITE" ]]
   then
     write_to_file $2 $3
  elif [[ $1 == "split" || $1 == "-split" ||$1 == "SPLIT" ]]
   then
     split $2 $3 $4
  elif [[ $1 == "hotpath" || $1 == "-hotpatch" || $1 == "HOTPATH" || $1 == "hotpatch" ]]
   then
     hot_path $2 $3
  elif [[ $1 == "laststr" || $1 == "-laststr" || $1 == "LASTSTR" ]]
   then
     get_last_str $2 $3
   elif [[ $1 == "firststr" || $1 == "-firststr" || $1 == "FIRSTSTR" ]]
    then
      get_first_str $2 $3
   elif [[ $1 == "nlaststr" || $1 == "-nlaststr" || $1 == "NLASTSTR" ]]
     then
       get_exclude_last_str $2 $3
   elif [[ $1 == "nfirststr" || $1 == "-nfirststr" || $1 == "NFIRSTSTR" ]]
     then
       get_exclude_first_str $2 $3
   elif [[ $1 == "replaceall" || $1 == "-replaceall" || $1 == "REPLACEALL" ]]
     then
       find_and_replace $2 $3
   elif [[ $1 == "find" || $1 == "-find" || $1 == "FIND" ]]
     then
       find_by_name $2 $3
   elif [[ $1 == "replace" || $1 == "-replace" || $1 == "REPLACE" ]]
     then
       replace_specify_file $3 $2
   elif [[ $1 == "javac" || $1 == "-javac" || $1 == "JAVAC" ]]
     then
       compile_java $2 $3
   elif [[ $1 == "javacims" || $1 == "-javacims" || $1 == "JAVACIMS" ]]
     then
       compile_java $2 '/home/acctuser/BES/var/domains/domain_ams/nodes/node_ams/instances/ims/deployments/apps/ims/WEB-INF'
   elif [[ $1 == "javacejb" || $1 == "-javacejb" || $1 == "JAVACEJB" ]]
     then
       compile_java $2 '/home/acctuser/BES/var/domains/domain_ams/nodes/node_ams/instances/ejb/deployments/apps/ejb'
   elif [[ $1 == "javacamsweb" || $1 == "-javacamsweb" || $1 == "JAVACAMSWEB" ]]
     then
       compile_java $2 '/home/acctuser/BES/var/domains/domain_ams/nodes/node_ams/instances/amsweb/deployments/apps/amsweb/WEB-INF'
   elif [[ $1 == "javacother" || $1 == "-javacother" || $1 == "JAVACOTHER" ]]
     then
       compile_java $2 '/home/acctuser/java_ams'
   elif [[ $1 == 'hotswap' || $1 == '-hotswap' || $1 == "HOTSWAP" ]]
     then
       hotswap_java $2 $3
   elif [[ $1 == 'findinfo' || $1 == '-findinfo' || $1 == "FINDINFO" ]]
     then
       find_info $2
   elif [[ $1 == 'grepfolder' || $1 == '-grepfolder' || $1 == "GREPFOLDER" ]]
     then
       grep_specified_folder $2 $3 $4
   elif [[ $1 == 'ls' || $1 == '-ls' || $1 == "LS" ]]
     then
       ls_size $2
   elif [[ $1 == 'querysharding' || $1 == '-querysharding' || $1 == "QUERYSHARDING" ]]
     then
       query_sharding $2 $3 '/home/acctuser/tools/fast_query_sharding' $4
   elif [[ $1 == 'monsysstart' || $1 == '-monsysstart' || $1 == "MONSYSSTART" ]]
     then
       monitor_system_start $2 $3 $4
   elif [[ $1 == 'monsysstop' || $1 == '-monsysstop' || $1 == "MONSYSSTOP" ]]
     then
       monitor_system_stop
   elif [[ $1 == 'getsql' || $1 == '-getsql' || $1 == "GETSQL" ]]
     then
       if [[ $2 == 'single' || $2 == '-single' || $2 == 'SINGLE' ]]
         then
           if [[ $3 == 'select' || $3 == 'update' || $3 == 'insert' || $3 == 'delete' ]]
             then
               # 如果不指定默认返回所有剔除重复之后的sql
               get_single_sql $4 $3
           else
               get_all_single_sql $3
            fi
       elif [[ $2 == 'select' || $2 == 'update' || $2 == 'insert' || $2 == 'delete'  ]]
          then
            get_specify_sql $3 $2
       else
            get_all_dml_sql $2
       fi

   elif [[ $1 == "help" || $1 == "-help" || $1 == "HELP" ]]
     then
       echo "find：列出指定文件夹下的所有文件名称  for example:  jef find '/home/acctuer/cz'"
       echo "write: 将指定内容写入到指定文件中 for example:  jef write '我是大好人' '/home/acctuer/cz/text.txt'"
       echo "split: 将指定内容按照指定分隔符分割并且获取指定下标的内容 第一个参数为内容，第二个为分隔符 for example: jef split 'q|w|e|r|t' '|' 2"
       echo "hotpatch: 将指定jar包中的指定class替换掉(就是常说的塞包) for excample: jef hotpatch /home/acctuser/java_ams/ams/ams-core-1.2.3-cloud-rm-snapshot-impl.jar /home/acctuser/cz/hotswap/class/QueryBePayBillFeeBusiness.class"
       echo "laststr: 获取指定字符串中被指定字符分割后的最后一个字符 jef laststr q|w|e '|' 结果为e"
       echo "firststr: 获取指定字符串中被指定字符分割后的第一个字符 jef laststr q|w|e '|' 结果为q"
       echo "nlaststr: 获取指定字符串中被指定字符分割后的除去最后一个字符的其他字符 jef laststr q|w|e '|' 结果为q|w|"
       echo "nfirststr: 获取指定字符串中被指定字符分割后的除去第一个字符的其他字符 jef laststr q|w|e '|' 结果为|w|e"
       echo "sedall: 查找并替换系统中所有名字相同的文件 jef sedall '/home/acctuser' 'test.txt' 结果为成功替换系统中n个路径下的文件"
       echo "find: 查找系统中所有名字相同的文件 jef find '/home/acctuser' 'test.txt' 结果展示系统中所有名字为test.txt的全路径"
       echo "replace: 换系统中指定目录的文件 jef replace '/home/acctuser' 'test.txt' "
       echo "javac: 自动编译java代码 jef javac './test.java' '/home/BES/xxxx' "
       echo "javacims: 编译信管代码 jef javacims './test.java'"
       echo "javacejb: 编译ejb代码 jef javacejb './test.java'"
       echo "javacamsweb: 编译web代码 jef javacamsweb './test.java'"
       echo "javacother: 编译后台进程代码 jef javacother './test.java'"
       echo "hotswap: 自动热替换class文件 jef hotswap './test.java' ims "
       echo "findinfo: find并展示详细信息 jef findinfo 'test.txt'"
       echo "grepfolder：多线程grep指定文件夹下的所有文件中的关键字 第一个参数为目标路径，第二个参数为目标关键字，第三个参数为指定的线程数，如果不写默认为五个线程。for example:jef grep /home/acctuser 'teststr' 5 "
       echo "ls：查看文件大小，参数为 g m  k for excample: jef ls -g 或者 jef ls m"
       echo "monsysstart: 开始启动监听系统性能指标 for example : jef monsysstart（生成的文件默认保存路径为家目录下的tools/nmonData/）或者 jef monsystart xx1 xx2 xx3(其中xx1为监听频率单位是ms,xx2为监听次数，xx3为监听文件保存位置)"
       echo "monsysstop: 停止监听系统性能指标,当结束监听后，可到指定文件夹下下载文件，然后使用工具分析 for example : jef monsysstop"
       echo "getsql: 用于获取账管信管日志中的sql语句，使用方式如下"
       echo "         forexample1: 如果需要获取带有参数和耗时的sql语句请使用 jef getsql xxx.log"
       echo "         forexample2: 如果需要获取指定操作且带有参数和耗时的sql语句请使用 jef getsql select xxx.log、jef getsql insert xxx.log等"
       echo "         forexample3: 如果需要获取所有简单sql语句请使用 jef getsql singele xxx.log"
       echo "         forexample4: 如果需要获取指定操作的简单sql语句请使用 jef getsql singele select xxx.log、jef getsql single update xxx.log等"
       echo "querysharding: 用于获取账管分表规则，指定表名 日期，以及可选的账户号， forexample: jef querysharding ca_bill 202307 31070038925 或者 jef -querysharding ca_bill 202307"
  fi
fi
#main
#get_last_str $1 $2
#hot_path $1 $2
#get_folder_filename $1
#write_to_file $1 $2
#echo "批量命令执行完毕"
